/**
 * DataAccessor.js
 * 单数据/累计数据访问器, 组装数据查询参数
 *
 * created by qiuwei
 * version 1.0.0
 * 2016年03月31日
 */

import merge from 'lodash/merge';
import isArray from 'lodash/isArray';
import mergeWith from 'lodash/mergeWith';
import assign from 'lodash/assign';

import rp from '../requestProxy';

function customerizer(objValue, srcValue) {
	if (isArray(objValue))
		return objValue.concat(srcValue);
}

export const BASE_STRUCT = {
	data: {
		target: '',
		data_type: '',
		type: 'normal'
	},
	// 默认为累计数据, 设置为空字符串则为单数据
	package_type: 'total',
	time_unit: '',
	multi_unit: '',
	filter: []
};

export const ENUM_TIME_UNIT = {
	NONE: 0,
	MONTH: 1,
	WEEK: 2,
	DAY: 3,
	HOUR: 4
};

export const ENUM_DATA_TYPE = {
	COUNT: 'count',
	SUM: 'sum',
	AVG: 'avg'
};

export const ENUM_PACKAGE_TYPE = {
	TOTAL: 'total',
	NONE: ''
};

/**
 * 数据访问者类
 */
export default class DataAccessor {
	constructor(tableName, fieldName, url) {
		this._tableName = tableName;
		this._fieldName = fieldName;
		this._url = url;

		merge(this._parameterObject, BASE_STRUCT, { data: { target: `${this._tableName}-${this._fieldName}` } });
	}

	_tableName = '';
	_fieldName = '';
	_url = '';

	_parameterObject = {};

	dataType(type) {
		merge(this._parameterObject, { data: { data_type: type } });

		return this;
	}

	packageType(type) {
		merge(this._parameterObject, { package_type: type });

		return this;
	}

	province(provinceId, title = this._tableName) {
		let provinceLimit = {
			item: `${title}-province_id`,
			type: '=',
			value: provinceId
		};
		
		mergeWith(this._parameterObject, { filter: [ provinceLimit ]}, customerizer);

		return this; 
	}

	city(cityId, title = this._tableName) {
		let cityLimit = {
			item: `${title}-city_id`,
			type: '=',
			value: cityId
		};
		
		mergeWith(this._parameterObject, { filter: [ cityLimit ]}, customerizer);

		return this;
	}

	county(countyId, title = this._tableName) {
		let countyLimit = {
			item: `${title}-county_id`,
			type: '=',
			value: countyId
		};
		
		mergeWith(this._parameterObject, { filter: [ countyLimit ]}, customerizer);

		return this;
	}

	school(schoolId, title = this._tableName) {
		let schoolLimit = {
			item: `${title}-school_id`,
			type: '=',
			value: schoolId
		};
		
		mergeWith(this._parameterObject, { filter: [ schoolLimit ]}, customerizer);

		return this;
	}

	dateRange(start, end) {
		let startLimit = {
			item: `${this._tableName}-day`,
			type: '>=',
			value: start,
			char: 'timestart'
		}, endLimit = {
			item: `${this._tableName}-day`,
			type: '<=',
			value: end,
			char: 'timeend'
		};
		
		mergeWith(this._parameterObject, { filter: [ startLimit, endLimit ]}, customerizer);

		return this;
	}

	grade(value, title = this._tableName) {
		let gradeLimit = {
			item: `${title}-grade`,
			type: 'in',
			value: value.join(',')
		};

		mergeWith(this._parameterObject, { filter: [ gradeLimit ]}, customerizer);

		return this;
	}

	subject(value, title = this._tableName) {
		let gradeLimit = {
			item: `${title}-subject`,
			type: 'in',
			value: value.join(',')
		};

		mergeWith(this._parameterObject, { filter: [ gradeLimit ]}, customerizer);

		return this;
	}

	customerize(value, item, type) {
		let customLimit = {
			item,
			type,
			value
		};

		mergeWith(this._parameterObject, { filter: [ customLimit ]}, customerizer);

		return this;
	}

	timeUnit(unit) {
		assign(this._parameterObject, { time_unit: unit });

		return this;
	}

	multiUnit(unit) {
		assign(this._parameterObject, { multi_unit: unit });

		return this;
	}

	multiUnitEx(unit) {
		assign(this._parameterObject, {multi_unit_ex: unit});

		return this;
	}

	rank() {
		merge(this._parameterObject, { data: { type: 'rank' } });

		return this;
	}

	rankReverse() {
		merge(this._parameterObject, { data: { type: 'rank-r' } });

		return this;
	}

	getData() {
		return rp.post(this._url, this._parameterObject);
	}

	jsonObject() {
		return (this._parameterObject);
	}
}